package com.supermali.creater;

import com.supermali.behavior.forward.land.MoveRateControl;
import com.supermali.creater.img.ImgLoader;
import com.supermali.entity.MapImageAbstract;
import com.supermali.entity.map.background.dynamic.DynamicBackGroundMapAbstract;
import com.supermali.entity.map.background.statics.StaticBackGroundMapAbstract;
import com.supermali.entity.map.hinder.HinderMapAbstract;
import com.supermali.entity.npc.NPCAbstract;
import com.supermali.entity.npc.bullet.BulletAbstract;
import com.supermali.entity.npc.finish.FinishAbstract;
import com.supermali.entity.npc.monistor.MonistorAbstract;
import com.supermali.entity.npc.person.Person;
import com.supermali.xml.EntityDom;
import com.supermali.xml.XmlExplain;

import java.awt.*;
import java.util.*;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @project super-mali
 * @Date 2021/2/27
 * @Auth yangrui
 **/
public class MapCreater {

    // 静态阻碍物
    private List<HinderMapAbstract> hinderMapAbstracts;
    // 动态怪物
    private List<MonistorAbstract> monistorAbstracts;
    // 静态背景
    private List<StaticBackGroundMapAbstract> staticBackgroundAbstracts;
    // 动态背景
    private List<DynamicBackGroundMapAbstract> dynamicBackgroundAbstracts;
    // 结束标志
    private List<FinishAbstract> finishAbstracts;
    // xml解析器
    private XmlExplain xmlExplain;
    // 绝对地址
    private double absoluteWidth;

    private MoveRateControl moveRateControl;
    // 人物元素
    private Person person;
    // 炮弹
    private List<BulletAbstract> bulletAbstracts;
    // 将要移除的元素集合
    private List<MapImageAbstract> removes;

    ImgLoader imgLoader;

    MoveRateControl rateControl;
    // 地图元素状态
    private GameStarter gameStarter;

    public MapCreater(GameStarter gameStarter) {

        absoluteWidth = 0;
        // 加载地图元素的图片
        imgLoader = new ImgLoader();
        imgLoader.loadMapFactor();
        xmlExplain = new XmlExplain();
        hinderMapAbstracts = new ArrayList<>();
        monistorAbstracts = new ArrayList<>();
        staticBackgroundAbstracts = new ArrayList<>();
        dynamicBackgroundAbstracts = new ArrayList<>();
        finishAbstracts=new ArrayList<>();
        rateControl = new MoveRateControl();

        bulletAbstracts=new ArrayList<>();
        removes = new LinkedList<>();
        moveRateControl=new MoveRateControl();
        this.gameStarter = gameStarter;
    }

    /**
     * 构建动态的地图元素
     * */
    public void loadDynamicMapFactor(int width,int height){
        List<EntityDom> result = xmlExplain.getResult();
        Map<String, EntityDom> entityDomMap = result.stream().collect(Collectors.toMap(EntityDom::toString, item -> item));
        // 已经显示的元素，就移除
        ArrayList<EntityDom> removes = new ArrayList<>();
        // 按照order排序
        List<EntityDom> resultCopy = result.stream().sorted(Comparator.comparing(EntityDom::getOrder)).collect(Collectors.toList());
        for(EntityDom dom: resultCopy){
            float startx = dom.getX()<0?0:dom.getX();
            float starty = dom.getY() < 0 ? 0 : dom.getY();
            // 如果在可视范围内，就加入
            boolean isX = startx*16 >= absoluteWidth && startx*16 < absoluteWidth + width;
            if(isX){
                if(dom.getShape() == EntityDom.DrawShape.NORMAL){
                    createNormal(dom);
                }else if(dom.getShape() == EntityDom.DrawShape.STAIRS){
                    createStairs(dom);
                }else if(dom.getShape()==EntityDom.DrawShape.REVERSE_STAIRS){
                    createReverseStair(dom);
                }
                EntityDom entityDom = entityDomMap.get(dom.toString());
                if(entityDom!=null) {
                    removes.add(entityDom);
                }
            }
        }
        if(removes.size()>0){
            result.removeAll(removes);
        }
    }

    /**
     * 创建普通的单个元素
     * */
    private void createNormal(EntityDom dom){
        float x = dom.getX();
        float y = dom.getY();
        int startx = dom.getCx()>0?0:dom.getCx();
        int starty = dom.getCy() > 0 ? 0 : dom.getCy();
        int endx = dom.getCx()>0?dom.getCx():0;
        int endy = dom.getCy()>0?dom.getCy():0;
        for(int i=startx;i<endx;i++){
            for(int j=starty;j<endy;j++){
                Object instance = dom.createInstance((x+i) * 16-absoluteWidth, (y+j) * 16,this);
                addToMap(instance);
            }
        }
    }

    private void  addToMap(Object instance){
        if(instance instanceof HinderMapAbstract){
            hinderMapAbstracts.add((HinderMapAbstract) instance);
        }else if(instance instanceof MonistorAbstract){
            monistorAbstracts.add((MonistorAbstract) instance);
        }else if(instance instanceof StaticBackGroundMapAbstract){
            staticBackgroundAbstracts.add((StaticBackGroundMapAbstract) instance);
        }else if(instance instanceof DynamicBackGroundMapAbstract){
            dynamicBackgroundAbstracts.add((DynamicBackGroundMapAbstract) instance);
        }else if(instance instanceof FinishAbstract){
            finishAbstracts.add((FinishAbstract) instance);
        }else if(instance instanceof NPCAbstract){

        }
    }
    /**
     * 创建正梯形地图
     * */
    private void createStairs(EntityDom dom){
        float x = dom.getX();
        float y = dom.getY();
        int cy = dom.getCy();
        int cx = dom.getCx();
        for(int i=0;i<cx;i++){
            for(int j=0;j<=i;j++){
                Object instance = dom.createInstance((x+i) * 16-absoluteWidth, (y+j) * 16,this);
                addToMap(instance);
            }
        }
    }
    /**
     * 创建反向梯形图
     * */
    private void createReverseStair(EntityDom dom){
        float x = dom.getX();
        float y = dom.getY();
        int cy = dom.getCy();
        int cx = dom.getCx();
        for(int i=cx;i>0;i--){
            for(int j=i-1;j>=0;j--){
                Object instance = dom.createInstance((x+cx-i) * 16-absoluteWidth, (y+j) * 16,this);
                addToMap(instance);
            }
        }
    }

    public void show(Graphics graphics){
        /*for(StaticBackGroundMapAbstract backGroundMapAbstract: staticBackgroundAbstracts){
            backGroundMapAbstract.make(graphics);
        }
        for(FinishAbstract finishAbstract: finishAbstracts){
            finishAbstract.make(graphics);
        }
        for(DynamicBackGroundMapAbstract backGroundMapAbstract: dynamicBackgroundAbstracts){
            backGroundMapAbstract.make(graphics);
        }
        for(MonistorAbstract monistorAbstract: monistorAbstracts){
            monistorAbstract.make(graphics);
        }
        for(HinderMapAbstract backGroundMapAbstract: hinderMapAbstracts){
            backGroundMapAbstract.make(graphics);
        }
        for(BulletAbstract bulletAbstract: bulletAbstracts){
            bulletAbstract.make(graphics);
        }*/
        // 增加排序
        List<MapImageAbstract> imageAbstracts = new ArrayList<>();
        imageAbstracts.addAll(staticBackgroundAbstracts);
        imageAbstracts.addAll(finishAbstracts);
        imageAbstracts.addAll(dynamicBackgroundAbstracts);
        imageAbstracts.addAll(monistorAbstracts);
        imageAbstracts.addAll(hinderMapAbstracts);
        imageAbstracts.addAll(bulletAbstracts);
        imageAbstracts = imageAbstracts.stream().sorted(Comparator.comparing(MapImageAbstract::getOrder)).collect(Collectors.toList());
        for(MapImageAbstract bulletAbstract: imageAbstracts){
            bulletAbstract.make(graphics);
        }

    }

    public void proccessData(long delta){
        if(person!=null) {
            person.proccessData(delta);
        }
        for(StaticBackGroundMapAbstract backGroundMapAbstract: staticBackgroundAbstracts){
            backGroundMapAbstract.proccessData(delta);
        }
        for(DynamicBackGroundMapAbstract backGroundMapAbstract: dynamicBackgroundAbstracts){
            backGroundMapAbstract.proccessData(delta);
        }
        for(MonistorAbstract monistorAbstract: monistorAbstracts){
            monistorAbstract.proccessData(delta);
        }
        for(HinderMapAbstract hinderMapAbstract: hinderMapAbstracts){
            hinderMapAbstract.proccessData(delta);
        }
        for(BulletAbstract bulletAbstract: bulletAbstracts){
            bulletAbstract.proccessData(delta);
        }
        for(FinishAbstract finishAbstract: finishAbstracts){
            finishAbstract.proccessData(delta);
        }
        // 移除需要移除的元素
        for(MapImageAbstract imageAbstract:removes){
            if(imageAbstract instanceof HinderMapAbstract){
                hinderMapAbstracts.remove(imageAbstract);
            }else if(imageAbstract instanceof BulletAbstract){
                bulletAbstracts.remove(imageAbstract);
            }else if(imageAbstract instanceof MonistorAbstract){
                monistorAbstracts.remove(imageAbstract);
            }else if(imageAbstract instanceof DynamicBackGroundMapAbstract){
                dynamicBackgroundAbstracts.remove(imageAbstract);
            }
        }
    }

    public void setPerson(Person person) {
        this.person = person;
    }

    // 移动
    public void moveForworld(int width,int height, long delta){
        double move1 = moveRateControl.move(delta, 1);
        this.absoluteWidth +=move1;
        loadDynamicMapFactor(width,height);
        double move = rateControl.move(delta, -1);
        // 移动hiner
        for(HinderMapAbstract hinderMapAbstract: hinderMapAbstracts){
            double x = hinderMapAbstract.getX();
            x+=move;
            hinderMapAbstract.setX(x);
        }
        // 移动怪物
        for(MonistorAbstract monistorAbstract: monistorAbstracts){
            double x = monistorAbstract.getX();
            x+=move;
            monistorAbstract.setX(x);
        }
        // 移动动态背景
        for(DynamicBackGroundMapAbstract dynamicBackGroundMapAbstract: dynamicBackgroundAbstracts){
            double x = dynamicBackGroundMapAbstract.getX();
            x+=move;
            dynamicBackGroundMapAbstract.setX(x);
        }
        // 移动结束图片
        for(FinishAbstract finishAbstract: finishAbstracts){
            double x = finishAbstract.getX();
            x+=move;
            finishAbstract.setX(x);
        }
    }

    public List<HinderMapAbstract> getHinderMapAbstracts() {
        return hinderMapAbstracts;
    }

    public List<MonistorAbstract> getMonistorAbstracts() {
        return monistorAbstracts;
    }

    public List<DynamicBackGroundMapAbstract> getDynamicBackgroundAbstracts() {
        return dynamicBackgroundAbstracts;
    }

    public Person getPerson() {
        return person;
    }

    public List<BulletAbstract> getBulletAbstracts() {
        return bulletAbstracts;
    }

    public List<MapImageAbstract> getRemoves() {
        return removes;
    }

    public List<FinishAbstract> getFinishAbstracts() {
        return finishAbstracts;
    }

    public GameStarter getGameStarter() {
        return gameStarter;
    }

    public void explainXml(String path){
        xmlExplain.explain(path);
    }

    public void clear(){
        staticBackgroundAbstracts = new ArrayList<>();
        finishAbstracts = new ArrayList<>();
        dynamicBackgroundAbstracts = new ArrayList<>();
        monistorAbstracts = new ArrayList<>();
        hinderMapAbstracts = new ArrayList<>();
        bulletAbstracts = new ArrayList<>();
        this.absoluteWidth=0;
    }
}
